package com.kly.sc.api.application.controller.product;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.base.services.redis.RedisClient;
import com.fqgj.common.api.Response;
import com.fqgj.common.api.annotations.ParamsValidate;
import com.fqgj.common.utils.CollectionUtils;
import com.kly.dto.*;
import com.kly.enums.Benefits;
import com.kly.enums.ProductCategory;
import com.kly.sc.api.application.controller.product.request.ProductRequest;
import com.kly.sc.api.application.controller.product.response.*;
import com.kly.sc.api.application.helper.RequestLocalInfo;
import com.kly.sc.api.application.service.product.ProductApiService;
import com.kly.sc.api.application.service.utils.BaseComponent;
import com.kly.sc.api.application.utils.BaseUtils;
import com.kly.sc.api.application.utils.Result;
import com.kly.sc.api.application.utils.RpcUtils;
import com.kly.sc.api.infras.app.RequestBasicInfo;
import com.kly.sc.api.infras.exception.ApplicationException;
import com.kly.sc.api.infras.utils.StringUtils;
import com.kly.service.*;
import com.kly.user.dto.UserPromotionRecordDto;
import com.kly.user.enums.RememberTime;
import com.kly.user.service.UserPromotionRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/member/product")
@Api(value = "/api/member/product", tags = "会员商品")
public class ProductController extends BaseComponent {

    @Resource
    ProductService productService;
    @Resource
    ProductCategoryService productCategoryService;
    @Resource
    MemberService memberService;
    @Autowired
    RedisClient redisClient;
    @Resource
    private UserPromotionRecordService userPromotionRecordService;
    @Resource
    private ProductDiscountConfigService productDiscountConfigService;
    @Resource
    private ProductApiService productApiService;

    private final static String PRODUCT = "Product";
    // appSource: 1-android, 2-ios
    private final static String app_source_ios = "2";
    @Resource
    TOrderService orderService;

    /**
     * 新产品的生效起始版本
     */
    @NacosValue(value = "${product.start.version}", autoRefreshed = true)
    private Integer productStartVersion;
    /**
     * pp产品隐藏开关
     */
    @NacosValue(value = "${product.pp1.enable.switch}", autoRefreshed = true)
    private Integer productPP1EnableSwitch;
    /**
     * pv1产品隐藏开关
     */
    @NacosValue(value = "${product.pv1.enable.switch}", autoRefreshed = true)
    private Integer productPV1EnableSwitch;

    @ResponseBody
    @RequestMapping(value = "/list")
    public Response productList(@RequestBody ProductRequest productRequest) {

        final String appCode = RequestLocalInfo.getRequestBasicInfo().getAppCode();
        if (StringUtils.isEmpty(appCode)) {
            throw new ApplicationException("The request params: appCode should not be empty!");
        }
        if (productRequest.getProductCategory()==0){
            productRequest.setProductCategory(null);
        }
        final List<ProductDto> productDtos = RpcUtils.getResult(productService.queryProductsByProductCategory(appCode, productRequest.getProductCategory()));
        if (CollectionUtils.isEmpty(productDtos)) {
            return Response.ok();
        }

        final List<ProductResp> productResps = productDtos.stream().map(o -> {
            ProductResp resp = ProductResp.builder().build();
            BeanUtils.copyProperties(o, resp);
            String productConfig = Optional.ofNullable(o.getProductConfig()).orElse("");
            final JSONObject config = JSONObject.parseObject(productConfig);
            resp.setBenefitDays(config.getString("membershipDays"));
            // 产品属性
            resp.setBenefits(config.getJSONArray("benefits"));
            // 产品享受的权益介绍
            resp.setTips(config.getJSONObject("tips"));
            return resp;
        }).collect(Collectors.toList());

        // 按照 productCategory 属性拆分为多个列表
//        Map<Integer, List<ProductResp>> groupedMap = productResps.stream()
//                .collect(Collectors.groupingBy(ProductResp::getProductCategory));
//
//        return Response.ok(groupedMap);

        return Response.ok(productResps);


    }

    @ResponseBody
    @PostMapping(value = "/newcomer/welcomePack")
    @ApiOperation("【meboo-v3.2】【新增】新手礼包弹窗")
    public Result<WelcomePackPopVO> newcomerWelcomePack() {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        final RequestBasicInfo requestBasicInfo = RequestLocalInfo.getRequestBasicInfo();
        return productApiService.newcomerWelcomePack(userCode, requestBasicInfo);
    }

    /**
     *
     * @return  修改缓存中产品信息
     */
    @ResponseBody
    @RequestMapping(value = "/refCache")
    public Response refreshCache() {
        Response<List<ProductDto>> listResponse =
                productService.queryProductsByProductCategory(null, null);

        List<ProductDto> productList = listResponse.getData();
        if (productList != null && !productList.isEmpty()) {
            for (ProductDto productDto : productList) {
                redisClient.set("key_{}_{}_{}", JSONUtil.toJsonStr(productDto),
                        RememberTime.ONE_DAY.getTime(), productDto.getAppCode(), PRODUCT, productDto.getProductCode());
            }
        }
        return Response.ok();
    }


    @ResponseBody
    @RequestMapping(value = "/page")
    @ParamsValidate
    public Response productPage() {

        final String appCode = RequestLocalInfo.getRequestBasicInfo().getAppCode();
        if (StringUtils.isEmpty(appCode)) {
            throw new ApplicationException("The request params: appCode should not be empty!");
        }
        final List<AllProductDto> productDtos = RpcUtils.getResult(productService.queryAllProduct(appCode));
        if (CollectionUtils.isEmpty(productDtos)) {
            return Response.ok();
        }
        final List<ProductDetailVO> productDetailVOS = productDtos.stream().map(o -> {
            ProductDetailVO vo = ProductDetailVO.builder().build();
            BeanUtils.copyProperties(o, vo);
            final String productCategoryDesc = o.getProductCategoryDesc();
            try {
                final JSONObject jsonObject = JSONObject.parseObject(productCategoryDesc);
                vo.setProductTips(jsonObject.getString("tip"));
                vo.setProductCategoryDesc(jsonObject.getString("content"));
            } catch (Exception e) {
                vo.setProductTips(o.getProductCategoryDesc());
                vo.setProductCategoryDesc(o.getProductCategoryDesc());
            }
            return vo;
        }).collect(Collectors.toList());


        return Response.ok(productDetailVOS);
    }
    @ResponseBody
    @RequestMapping(value = "/category")
    public Response QueryProductCategory(@RequestBody ProductRequest productRequest) {
        String appCode = RequestLocalInfo.getRequestBasicInfo().getAppCode();
        final String appSource = RequestLocalInfo.getRequestBasicInfo().getAppSource();
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();

        int havaDiscount = 0;
        int popOverTime = 0;
        Integer promotionType = 0;
        if (productRequest.getProductCategory() == 1) {
            UserPromotionRecordDto userPromotionRecordDto = userPromotionRecordService.getUserPromotion(userCode);
            if (userPromotionRecordDto != null && (userPromotionRecordDto.getEndDate().after(new Date()) && userPromotionRecordDto.getOperationStatus() == 1)) {
                havaDiscount = 1;
                promotionType = userPromotionRecordDto.getPromotionType();
                long nowDate = System.currentTimeMillis();
                long endDate = userPromotionRecordDto.getEndDate().getTime();
                popOverTime = (int) ((endDate - nowDate) / 1000);

                /**
                 *类型 1折扣促销 2用户拉新 3用户召回
                 */
                if (userPromotionRecordDto.getPromotionType() == 1) {
                    productRequest.setProductCategory(ProductCategory.USER_DISCOUNT.getCode());
                }

                if (userPromotionRecordDto.getPromotionType() == 3) {
                    productRequest.setProductCategory(ProductCategory.USER_BACK_DISCOUNT.getCode());
                }
            }
        }


        final ProductCategoryDto dto = RpcUtils.getResult(productCategoryService.queryProductCategory(appCode, productRequest.getProductCategory()));
        if (Objects.isNull(dto)) {
            throw new ApplicationException("The member config does not exists");
        }
        List<ProductCategoryDto.Subscriptions> subscriptions = dto.getSubscriptions();
        subscriptions.removeIf(o -> StringUtils.isEmpty(o.getTip()));

        List<ProductDescriptionVO> productList = null;
        List<SubscriptionsVO> subscriptionsVOS = null;
        if (CollectionUtils.isNotEmpty(subscriptions)) {
            // 配置非空， 以配置为主
//            if (StringUtils.isNotEmpty(getBenefitsDesc(appCode))) {
//                if (productRequest.getProductCategory() == ProductCategory.MEMBER.getCode()
//                        || (productRequest.getProductCategory() == ProductCategory.USER_DISCOUNT.getCode() || productRequest.getProductCategory() == ProductCategory.USER_BACK_DISCOUNT.getCode())) {
//                    subscriptions = JSONObject.parseArray(getBenefitsDesc(appCode), ProductCategoryDto.Subscriptions.class);
//                }
//            }

            subscriptionsVOS = subscriptions.stream().map(SubscriptionsVO::toVo).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(subscriptionsVOS) && ProductCategory.MEMBER.getCode() == productRequest.getProductCategory()) {
                subscriptionsVOS.removeIf(o -> Objects.equals(o.getTip(), "Exclusive Premium Badge"));
            }

            if (ProductCategory.IOS_MEBOO.getCode() == productRequest.getProductCategory()) {
                Boolean ifMember = RpcUtils.getResult(memberService.ifMember(userCode));
                if (ifMember) {
                    subscriptionsVOS.removeIf(o -> Objects.equals(o.getTip(), "Release Private Album"));
                    subscriptionsVOS.removeIf(o -> Objects.equals(o.getTip(), "Exclusive Premium Badge"));
                }
                if (productRequest.getFrom() != null && productRequest.getFrom() == 2) {
                    subscriptionsVOS.removeIf(o -> Objects.equals(o.getTip(), "Exclusive Premium Badge"));
                }
            }

            final List<ProductDescriptionDto> productDescriptions = dto.getSubscriptions().get(0).getProductDescriptions();
            filterProductDescriptions(productDescriptions, productRequest.getProductCategory());
            selectedProduct(productDescriptions, productRequest.getProductCategory());


            if (CollectionUtils.isNotEmpty(productDescriptions)) {
                productList = productDescriptions.stream().map(ProductDescriptionVO::toVo).collect(Collectors.toList());
                if(havaDiscount == 1){
                    for (ProductDescriptionVO productDescriptionVO : productList) {
                        ProductDiscountConfigDto productDiscountConfigDto = productDiscountConfigService.productDiscountCountByPromotionType(promotionType, appCode, productDescriptionVO.getSortBy());
                        if (productDiscountConfigDto != null) {
                            productDescriptionVO.setProductCode(productDiscountConfigDto.getProductCode());
                            productDescriptionVO.setPopTag(productDiscountConfigDto.getPopTag());
                            productDescriptionVO.setPromotionPrice(productDiscountConfigDto.getPromotionPrice());
                            productDescriptionVO.setPromotionNote(productDiscountConfigDto.getPromotionNote());
                            productDescriptionVO.setPopButtonTitle(productDiscountConfigDto.getPopButtonTitle());
                            productDescriptionVO.setPopButtonContent(productDiscountConfigDto.getPopButtonContent());
                        }
                    }
                } else {
                    if (!StringUtils.isNotEmpty(appSource) && app_source_ios.equals(appSource)) {
                        for (ProductDescriptionVO productDescriptionVO : productList) {
                            productDescriptionVO.setPopButtonTitle("Recurring billing. Cancel anytime.");
                            productDescriptionVO.setPopButtonContent("Payment will be charged to your Google Play account at the confirmation of purchase.Subscription automatically renews for the same package length at the same price unless it is canceled at least 24 hours before the end of the current period. Your account will be charged for renewal within 24 hours prior to the end of the current period. You can manage and cancel your subscriptions in account settings on the Google Play after purchase When the subscription benefits are adjusted,the adjusted benefits will be implemented in the next period.");
                        }
                    }

                }
            }
        }

        // 隐藏ppv&turnOns
        if (super.showPPPV()) {
            if (productRequest.getProductCategory() == ProductCategory.MEMBER.getCode()
                    || productRequest.getProductCategory() == ProductCategory.IOS_MEBOO.getCode()
                    || (productRequest.getProductCategory() == ProductCategory.USER_DISCOUNT.getCode()
                    || productRequest.getProductCategory() == ProductCategory.USER_BACK_DISCOUNT.getCode())) {
                subscriptionsVOS = subscriptionsVOS.stream().filter(SubscriptionsVO::getShowFlag).collect(Collectors.toList());
            }
        }

        final ProductCategoryVO productCategoryVO = ProductCategoryVO.builder().havaDiscount(havaDiscount).popOverTime(popOverTime).productDescriptions(productList).subscriptions(subscriptionsVOS)
                .productCategory(dto.getProductCategory()).productCategoryName(dto.getProductCategoryName()).refreshTime(BaseUtils.getSeconds(1) + getCountDownDelayTime(appCode)).build();

        return Response.ok(productCategoryVO);
    }

    /**
     * 低于指定版本的app，不需要显示新产品
     * 高版本对pp1/pv1的显示与隐藏控制
     */
    private void filterProductDescriptions(List<ProductDescriptionDto> productDescriptions, Integer productCategory) {
        if (CollectionUtils.isEmpty(productDescriptions)) {
            return;
        }

        final String appVersion = RequestLocalInfo.getRequestBasicInfo().getAppVersion();
        if (StringUtils.isEmpty(appVersion)) {
            return;
        }

        // 客户端低于指定版本的app不显示新产品
        if (Integer.parseInt(appVersion) < productStartVersion) {
            productDescriptions.removeIf(o -> o.getDefaultShowFlag() != null && o.getDefaultShowFlag() == 0);
            return;
        }

        // 客户端高于指定版本
        if (Integer.parseInt(appVersion) >= productStartVersion) {
            // 隐藏pp1产品
            if (productPP1EnableSwitch == 1) {
                if (ProductCategory.PRIVATE_PHOTO.getCode() == productCategory) {
                    productDescriptions.removeIf(o -> o.getProductCode() != null && o.getProductCode().equals("pp1"));
                }
            }
            // 隐藏pv1产品
            if (productPV1EnableSwitch == 1) {
                if (ProductCategory.PRIVATE_VIDEO.getCode() == productCategory) {
                    productDescriptions.removeIf(o -> o.getProductCode() != null && o.getProductCode().equals("pv1"));
                }
            }
        }
    }

    /**
     * PP默认选中
     *   1. 用户历史购买PP次数0≤X＜10，默认定位在10次
     *   2. 用户历史购买PP次数X≥10，默认定位在30次
     *
     * PV默认选中：
     *   1. 用户历史购买PP次数0≤X＜10，默认定位在10次
     *   2. 用户历史购买PV次数X≥10，默认定位在15次
     */
    private void selectedProduct(List<ProductDescriptionDto> productDescriptions, Integer productCategory) {
        final String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        final String appVersion = RequestLocalInfo.getRequestBasicInfo().getAppVersion();

        if (CollectionUtils.isEmpty(productDescriptions)) {
            return;
        }

        // 客户端低于指定版本不作处理
        if (Integer.parseInt(appVersion) < productStartVersion) {
            return;
        }

        final List<OrderSumDto> orderSumDtos = RpcUtils.getResult(orderService.listPaidOrders(userCode));
        Integer orderNum = 0;
        if (CollectionUtils.isNotEmpty(orderSumDtos)) {
            orderNum = orderSumDtos.stream().filter(o -> Objects.equals(o.getProductCategory(), productCategory)).findFirst().map(OrderSumDto::getNum).orElse(0);
        }

        if (ProductCategory.PRIVATE_PHOTO.getCode() == productCategory) {
            for (ProductDescriptionDto dto : productDescriptions) {
                dto.setCheck(Boolean.FALSE);
                dto.setTip(Strings.EMPTY);
                if (dto.getProductCode().equals("pp30")) {
                    dto.setCheck(orderNum >= 10);
                    dto.setTip(orderNum >=10 ? "Popular" : "Preferential");
                }

                if (dto.getProductCode().equals("pp10")) {
                    dto.setCheck(orderNum < 10);
                    dto.setTip(orderNum < 10 ? "Popular" : Strings.EMPTY);
                }

            }
        }

        if (ProductCategory.PRIVATE_VIDEO.getCode() == productCategory) {
            for (ProductDescriptionDto dto : productDescriptions) {
                dto.setCheck(Boolean.FALSE);
                dto.setTip(Strings.EMPTY);
                if (dto.getProductCode().equals("pv15")) {
                    dto.setCheck(orderNum >= 10);
                    dto.setTip(orderNum >=10 ? "Popular" : "Preferential");
                }

                if (dto.getProductCode().equals("pv10")) {
                    dto.setCheck(orderNum < 10);
                    dto.setTip(orderNum < 10 ? "Popular" : Strings.EMPTY);
                }

            }
        }

    }



        @ResponseBody
    @RequestMapping(value = "/subscription")
    public Response queryMemberSubscription() {

        String appCode = RequestLocalInfo.getRequestBasicInfo().getAppCode();
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();

        int havaDiscount = 0;
        int popOverTime = 0;
        int productCategory = ProductCategory.MEMBER.getCode();
        UserPromotionRecordDto userPromotionRecordDto = userPromotionRecordService.getUserPromotion(userCode);
        if (userPromotionRecordDto != null && (userPromotionRecordDto.getEndDate().after(new Date()) && userPromotionRecordDto.getOperationStatus() == 1)) {
            havaDiscount = 1;
            long nowDate = System.currentTimeMillis();
            long endDate = userPromotionRecordDto.getEndDate().getTime();
            popOverTime = (int) ((endDate - nowDate) / 1000);
            /**
             *类型 1折扣促销 2用户拉新 3用户召回
             */
            if (userPromotionRecordDto.getPromotionType() == 1) {
                productCategory = ProductCategory.USER_DISCOUNT.getCode();
            }

            if (userPromotionRecordDto.getPromotionType() == 3) {
                productCategory = ProductCategory.USER_BACK_DISCOUNT.getCode();
            }
        }


        Response<MemberDto> memberDtoResponse = memberService.queryMemberSubscription(
                RequestLocalInfo.getRequestBasicInfo().getAppCode(), getCurrentUserCode(), productCategory);
        memberDtoResponse.getData().setPopOverTime(popOverTime);
        memberDtoResponse.getData().setHavaDiscount(havaDiscount);

        List<ProductCategoryDto.Subscriptions> subscriptions = memberDtoResponse.getData().getSubscriptions();
        subscriptions.removeIf(o -> StringUtils.isEmpty(o.getTip()));

        final Boolean showPPPV = super.showPPPV();

        if (memberDtoResponse.isSuccess() && memberDtoResponse.getData() != null) {
            final String memberCode = memberDtoResponse.getData().getMemberCode();
//            if (StringUtils.isNotEmpty(memberCode)) {
//                subscriptions = JSONObject.parseArray(getMemberBenefitsDesc(appCode), ProductCategoryDto.Subscriptions.class);
//                memberDtoResponse.getData().setSubscriptions(subscriptions);
//            } else {
                final ProductCategoryDto.Subscriptions memberDescription = memberDtoResponse.getData().getMemberDescription();
                if (StringUtils.isNotEmpty(memberCode)) {
                    memberDescription.setContent("Enjoy 5 premium benefits");

                } else {
                    memberDescription.setContent("Enjoy 7 premium benefits");
                }

                if (showPPPV) {
                    memberDescription.setContent("Enjoy 3 premium benefits");
                }
                memberDtoResponse.getData().setMemberDescription(memberDescription);
                memberDtoResponse.getData().setSubscriptions(subscriptions);

//            }

            final List<ProductCategoryDto.Subscriptions> subscriptionsList = memberDtoResponse.getData().getSubscriptions();
            if (showPPPV) {
                final List<ProductCategoryDto.Subscriptions> filterPPPVSubscriptions = subscriptionsList.stream().filter(ProductCategoryDto.Subscriptions::isShowFlag).collect(Collectors.toList());
                memberDtoResponse.getData().setSubscriptions(filterPPPVSubscriptions);
            }

            if (havaDiscount == 1) {
                List<ProductDescriptionDto> productDescriptionDtoList = memberDtoResponse.getData().getProductDescriptions();
                for (ProductDescriptionDto productDescriptionDto : productDescriptionDtoList) {
                    ProductDiscountConfigDto productDiscountConfigDto = productDiscountConfigService.productDiscountCountByPromotionType(userPromotionRecordDto.getPromotionType(), appCode, productDescriptionDto.getSortBy());
                    if (productDiscountConfigDto != null) {
                        productDescriptionDto.setProductCode(productDiscountConfigDto.getProductCode());
                        productDescriptionDto.setPromotionPrice(productDiscountConfigDto.getPromotionPrice());
                        productDescriptionDto.setPopTag(productDiscountConfigDto.getPopTag());
                        productDescriptionDto.setPromotionNote(productDiscountConfigDto.getPromotionNote());
                        memberDtoResponse.getData().getMemberDescription().setHeader("Limited-time Special");
                    }
                }
                memberDtoResponse.getData().setProductDescriptions(productDescriptionDtoList);
            }

        }
        return memberDtoResponse;

    }
}
